medusa-plugin-reviews-and-ratings
Version:
Medusa plugin to add product reviews and ratings functionality in the project.
147 lines (146 loc) • 6.12 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DELETE = exports.PUT = exports.POST = exports.GET = void 0;
const medusa_1 = require("@medusajs/medusa");
const product_review_1 = require("../../../../models/product-review");
const utils_1 = require("@medusajs/utils");
const fs_1 = __importDefault(require("fs"));
const image_1 = __importDefault(require("@medusajs/medusa/dist/repositories/image"));
const utils_2 = require("@medusajs/utils");
const GET = async (req, res) => {
const { id: product_id } = req.params;
const { limit, page } = req.query;
const parsedLimit = parseInt(limit, 10) || 0;
const parsedPage = parseInt(page, 10) || 0;
const offset = (parsedPage - 1) * parsedLimit < 0 ? 0 : (parsedPage - 1) * parsedLimit;
const manager = req.scope.resolve("manager");
const productReviewRepo = manager.getRepository(product_review_1.ProductReview);
const productRepo = manager.getRepository(medusa_1.Product);
const product = await productRepo.findOneBy({
id: product_id,
});
if (!product) {
throw new utils_2.MedusaError(utils_2.MedusaError.Types.NOT_FOUND, "Product not found");
}
const [reviews, ratings] = await Promise.all([
productReviewRepo.find({
where: { product: { id: product_id } },
relations: ["customer", "images"],
skip: offset,
take: parsedLimit,
order: {
created_at: "DESC",
},
}),
productReviewRepo.find({
select: ["rating"],
where: { product: { id: product_id } },
}),
]);
const star_wise_data = {
star_1: { total: 0, bar_percentage: 0 },
star_2: { total: 0, bar_percentage: 0 },
star_3: { total: 0, bar_percentage: 0 },
star_4: { total: 0, bar_percentage: 0 },
star_5: { total: 0, bar_percentage: 0 },
};
ratings.forEach((rating) => {
if (rating.rating > 0)
star_wise_data[`star_${rating.rating}`].total++;
});
const total_ratings = ratings.length;
Object.entries(star_wise_data).forEach(([key, value]) => (star_wise_data[key].bar_percentage =
(value.total / total_ratings) * 100 || 0));
const average_rating = ratings.reduce((total, rating) => total + rating.rating, 0) /
total_ratings || 0;
const total_pages = Math.ceil(total_ratings / parsedLimit)
? Math.ceil(total_ratings / parsedLimit)
: 1;
return res.json({
reviews,
total_ratings,
total_pages,
average_rating,
star_wise_data,
});
};
exports.GET = GET;
const POST = async (req, res) => {
const { id: product_id } = req.params;
const { customer_id } = req.user;
const { title, description, rating } = req.body;
const manager = req.scope.resolve("manager");
const fileService = req.scope.resolve("fileService");
const productRepo = manager.getRepository(medusa_1.Product);
const customerRepo = manager.getRepository(medusa_1.Customer);
const imageRepo = manager.withRepository(image_1.default);
const productReviewRepo = manager.getRepository(product_review_1.ProductReview);
const isProduct = await productRepo.findOneBy({
id: product_id,
});
if (!isProduct) {
throw new utils_2.MedusaError(utils_2.MedusaError.Types.NOT_FOUND, "Product not found");
}
const isReview = await productReviewRepo.findOneBy({
product: { id: product_id },
customer: { id: customer_id },
});
if (isReview) {
throw new utils_2.MedusaError(utils_2.MedusaError.Types.NOT_ALLOWED, "You can write review only once");
}
const imageUrls = await (0, utils_1.promiseAll)(req.files.map(async (f) => {
return fileService.upload(f).then((result) => {
fs_1.default.unlinkSync(f.path);
return result.url;
});
}));
const customer = await customerRepo.findOneBy({ id: customer_id });
const product = await productRepo.findOneBy({ id: product_id });
const images = await imageRepo.upsertImages(imageUrls);
const newReview = new product_review_1.ProductReview();
newReview.customer = customer;
newReview.product = product;
newReview.images = images;
newReview.title = title;
newReview.description = description;
newReview.rating = rating;
const review = await productReviewRepo.save(newReview);
return res.json(review);
};
exports.POST = POST;
const PUT = async (req, res) => {
const { id: product_review_id } = req.params;
const { title, description, rating } = req.body;
const manager = req.scope.resolve("manager");
const productReviewRepo = manager.getRepository(product_review_1.ProductReview);
const updatedReview = await productReviewRepo.findOneBy({
id: product_review_id,
});
if (!updatedReview) {
throw new utils_2.MedusaError(utils_2.MedusaError.Types.NOT_FOUND, "Review not found");
}
updatedReview.title = title;
updatedReview.description = description;
updatedReview.rating = rating;
const review = await productReviewRepo.save(updatedReview);
return res.json(review);
};
exports.PUT = PUT;
const DELETE = async (req, res) => {
const { id: product_review_id } = req.params;
const manager = req.scope.resolve("manager");
const productReviewRepo = manager.getRepository(product_review_1.ProductReview);
const review = await productReviewRepo.findOne({
where: { id: product_review_id },
relations: ["images"],
});
if (!review) {
throw new utils_2.MedusaError(utils_2.MedusaError.Types.NOT_FOUND, "Review not found");
}
await productReviewRepo.remove(review);
return res.send("Review deleted");
};
exports.DELETE = DELETE;